package com.cygsunri.multienergy.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cygsunri.common.constant.DeviceType;
import com.cygsunri.common.entity.QueryTemplate;
import com.cygsunri.common.service.CommonDataService;
import com.cygsunri.common.service.CommonService;
import com.cygsunri.common.service.SVGPathService;
import com.cygsunri.history.service.GeneralDataService;
import com.cygsunri.history.service.MutationDataService;
import com.cygsunri.historyCurve.entity.CurveQuery;
import com.cygsunri.historyCurve.entity.MutationDataSet;
import com.cygsunri.information.entity.Information;
import com.cygsunri.measurement.entity.Flag;
import com.cygsunri.measurement.entity.MeasurementInfo;
import com.cygsunri.measurement.entity.MeasurementValue;
import com.cygsunri.measurement.entity.RealTimeDataBean;
import com.cygsunri.multienergy.api.dto.HisData;
import com.cygsunri.multienergy.api.dto.HisDataList;
import com.cygsunri.scada.base.BasePSR;
import com.cygsunri.scada.service.ScadaPSRService;
import com.cygsunri.template.entity.display.DisplayArea;
import com.cygsunri.template.entity.display.DisplayTemplate;
import com.cygsunri.template.entity.display.DisplayTemplateData;
import com.cygsunri.template.entity.psr.DeviceTemplate;
import com.cygsunri.template.entity.psr.DeviceTemplateData;
import com.cygsunri.template.service.*;
import com.cygsunri.util.TimeUtil;
import com.github.abel533.echarts.Legend;
import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.series.Line;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 启橙多能运维API
 *
 *
 */

@RestController
@RequestMapping("/api/v2")
public class MultiEnergyController {

    @Autowired
    private CommonService commonService;

    @Autowired
    private GeneralDataService generalDataService;

    @Autowired
    private CommonDataService commonDataService;

    @Autowired
    private MutationDataService mutationDataService;

    @Autowired
    private ScadaPSRService scadaPSRService;

    @Autowired
    private DeviceTemplateDataService deviceTemplateDataService;

    @Autowired
    private PSRTemplateMappingService psrTemplateMappingService;

    @Autowired
    private DisplayTemplateService displayTemplateService;

//    @Autowired
//    private DisplayAreaService displayAreaService;

    @Autowired
    private DisplayTemplateDataService displayTemplateDataService;

    @Autowired
    private SVGPathService svgPathService;


    @RequestMapping(value = "/measurement/general", method = RequestMethod.GET)
    public ResponseEntity<MeasurementValue> getGeneralValues(@RequestParam("deviceId") String psrID, @RequestParam("dataName") String name) {
        BasePSR device = scadaPSRService.getDeviceByPsrId(psrID);
        if (device == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        MeasurementValue m = new MeasurementValue().setO(device).setName(name).setRdb(true);
        return new ResponseEntity<>(generalDataService.getValueFillDisPlay(m), HttpStatus.OK);
    }



    @RequestMapping(value = "/svg/measurements", method = RequestMethod.POST)
    public ResponseEntity<List<MeasurementValue>> getNormalValues(@RequestBody List<MeasurementValue> measurementValues) {
        List<MeasurementValue> values = new ArrayList<>();
        for (MeasurementValue measurementValue : measurementValues) {
            MeasurementValue m = generalDataService.getValue(measurementValue);
            values.add(m);
        }
        return new ResponseEntity<>(values, HttpStatus.OK);
    }


    @RequestMapping(value = "/svg/path", method = RequestMethod.GET)
    public ResponseEntity<String> getSVGPath(@RequestParam("user") String user, @RequestParam("menu") String menu) {

        String path = svgPathService.getSVGPath(user, menu);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("path", path);
        return new ResponseEntity<>(jsonObject.toJSONString(), HttpStatus.OK);
    }


    /**
     * 根据用户权限获取所有厂站
     *
     * @return
     */
    @GetMapping(value = "/psr/get/all/substations")
    public ResponseEntity<List<BasePSR>> getSubstations(@RequestParam("user") String user, @RequestParam("type") String type) {

        List<BasePSR> substations = new ArrayList<>();

        if (type.equals("all") || type.equals("solar")) {
            List<BasePSR> solar = scadaPSRService.getDevicesByType(DeviceType.SOLAR_SUB.getKey());
            substations.addAll(solar);
        }

        if (type.equals("all") || type.equals("ess")) {
            List<BasePSR> ess = scadaPSRService.getDevicesByType(DeviceType.ESS_SUB.getKey());
            substations.addAll(ess);
        }

        if (type.equals("all") || type.equals("charge")) {
            List<BasePSR> charge = scadaPSRService.getDevicesByType(DeviceType.CHARGE_SUB.getKey());
            substations.addAll(charge);
        }

        if (type.equals("all") || type.equals("consumption")) {
            List<BasePSR> consumption = scadaPSRService.getDevicesByType(DeviceType.CONSUMPTION_SUB.getKey());
            substations.addAll(consumption);
        }

        if (type.equals("all") || type.equals("air")) {
            List<BasePSR> air = scadaPSRService.getDevicesByType(DeviceType.AIR_SUB.getKey());
            substations.addAll(air);
        }

        if (type.equals("all") || type.equals("wind")) {
            List<BasePSR> wind = scadaPSRService.getDevicesByType(DeviceType.WIND_SUB.getKey());
            substations.addAll(wind);
        }

        return new ResponseEntity<>(substations, HttpStatus.OK);
    }


    /**
     * 根据设备id获取设备模板
     * @param id
     * @return
     */
    @GetMapping(value = "psr/get/template/data")
    public ResponseEntity<List<QueryTemplate>> getHistoryCurveTemplate(@RequestParam("id") String id) {
        return new ResponseEntity<>(commonService.getHistoryTemplate(id), HttpStatus.OK);
    }

    /**
     * 根据父设备获取子设备列表
     * @param id
     * @return
     */
    @GetMapping(value = "psr/get/children/devices")
    public ResponseEntity getChildrenDevices(@RequestParam("id") String id) {
        List<BasePSR> basePSRS = scadaPSRService.getChildrenDevice(id);
        for (BasePSR basePSR : basePSRS) {
            List<BasePSR> list = scadaPSRService.getChildrenDevice(basePSR.getId());
            basePSR.setExtra(list.isEmpty());//回给前台判断子设备是否有叶子节点
        }
        return new ResponseEntity<>(basePSRS, HttpStatus.OK);
    }


    /**
     * 获取设备实时数据
     * @param deviceId
     * @return
     */
    @GetMapping(value = "/measurement/get/values")
    public ResponseEntity<Map<String, List<RealTimeDataBean>>> getValuesByDevice(@RequestParam("deviceId") String deviceId) {

        Map<String, List<RealTimeDataBean>> map = new HashMap<>();

        DeviceTemplate deviceTemplate = psrTemplateMappingService.getDeviceTemplateByMapping(deviceId);
        if (deviceTemplate == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        List<DeviceTemplateData> deviceTemplateDatas = deviceTemplateDataService.getDeviceTemplateDataListByDeviceTemplateId(deviceTemplate.getId());

        List<DeviceTemplateData> yxList = deviceTemplate.getDeviceTemplateByType(deviceTemplateDatas, 1);
        List<DeviceTemplateData> ycList = deviceTemplate.getDeviceTemplateByType(deviceTemplateDatas, 2);
        List<DeviceTemplateData> ymList = deviceTemplate.getDeviceTemplateByType(deviceTemplateDatas, 3);

        List<RealTimeDataBean> yxData = getRealTimeDataBean(yxList, "yx", deviceId);
        List<RealTimeDataBean> ycData = getRealTimeDataBean(ycList, "yc", deviceId);
        List<RealTimeDataBean> ymData = getRealTimeDataBean(ymList, "ym", deviceId);

        map.put("yx", yxData);
        map.put("yc", ycData);
        map.put("ym", ymData);
        return new ResponseEntity<>(map, HttpStatus.OK);

    }

    private List<RealTimeDataBean> getRealTimeDataBean(List<DeviceTemplateData> deviceTemplateDataList, String name, String psrID) {
        List<RealTimeDataBean> list = Lists.newArrayList();
        if (deviceTemplateDataList.size() > 0) {
            for (DeviceTemplateData data : deviceTemplateDataList) {
                MeasurementValue measurementValue = new MeasurementValue().setO(new BasePSR().setId(psrID)).setName(data.getName()).setRdb(true);
                measurementValue = generalDataService.getValue(measurementValue);
                RealTimeDataBean realTimeDataBean = new RealTimeDataBean()
                        .setMeasurementId(measurementValue.getKey())
                        .setMeasurementName(data.getComments().trim())
                        .setMeasurementValue(measurementValue)
                        .setMeasurementUnit(data.getUnit())
                        .setMeasurementType(name)
                        .setMeasurementIndex(data.getIndexNumber());

                list.add(realTimeDataBean);
            }
        }
        return list;
    }

    /**
     * modal层的历史数据
     * @param query
     * @return
     */
    @PostMapping(value = "/history/curve/single")
    public ResponseEntity<String> getHistoryCurveSingle(@RequestBody CurveQuery query) {

        Option option = new Option();
        CategoryAxis categoryAxis = new CategoryAxis();
        option.xAxis(categoryAxis);

        Legend legend = new Legend();
        option.legend(legend);

        String startTime = query.getStartTime();
        String endTime = query.getEndTime();
        Integer step = query.getStep();
        Boolean mutation = query.getMutation();

        int first = 0, current = 0;
        for (MeasurementInfo info : query.getMeasurementParams()) {
            Line line = new Line(info.getComments());
            option.series(line);
            legend.data(info.getComments());
            if (mutation) {
                List<MeasurementValue> list = mutationDataService.getMutationValue(info.getMeasurementID(), startTime, endTime, 1);
                for (MeasurementValue m : list) {
                    MutationDataSet mutationDataSet = new MutationDataSet();
                    mutationDataSet.setName(m.getDate() + " " + m.getTime());
                    String[] array = new String[2];
                    array[0] = m.getDate() + " " + m.getTime();
                    array[1] = m.isInValid() ? "-" : m.getData().toString();
                    mutationDataSet.setValue(array);
                    line.data(mutationDataSet);
                }

            } else {
                current++;
                List<MeasurementValue> list = commonDataService.getHistoryValue(info.getMeasurementID(), startTime, endTime, step, 2, false);
                if (!list.isEmpty()) {
                    if (first == 0) {
                        first = current;
                    }
                    for (MeasurementValue m : list) {
                        if (first == current) {
                            categoryAxis.data(m.getDate() + " " + m.getTime());
                        }
                        line.data(m.isInValid() ? "-" : m.getData());
                    }
                }
            }
        }
        return new ResponseEntity<>(JSON.toJSONString(option), HttpStatus.OK);
    }

    /**
     * 历史数据表格栏
     * @param query
     * @return
     */
    @PostMapping(value = "/history/get/dataList")
    public ResponseEntity<String> getHistoryDataList(@RequestBody CurveQuery query) {

        HisDataList retDataList = new HisDataList();

        String startTime = query.getStartTime();
        String endTime = query.getEndTime();
        Integer step = query.getStep();
        Boolean mutation = query.getMutation();

        int first = 0, current = 0;
        for (MeasurementInfo info : query.getMeasurementParams()) {
            HisData hisData = new HisData();
            hisData.setName(info.getComments());
            hisData.setUnit(info.getUnit());
            if (mutation) {
                List<MeasurementValue> list = mutationDataService.getMutationValue(info.getMeasurementID(), startTime, endTime, 1);
                for (MeasurementValue m : list) {

                    String[] array = new String[2];
                    array[0] = m.getDate() + " " + m.getTime();
                    array[1] = m.isInValid() ? "-" : m.getData().toString();
                }

            } else {
                current++;
                List<MeasurementValue> list = commonDataService.getHistoryValue(info.getMeasurementID(), startTime, endTime, step, 2, false);
                if (!list.isEmpty()) {
                    if (first == 0) {
                        first = current;
                    }
                    for (MeasurementValue m : list) {
                        if (first == current) {
                            retDataList.getTimeRange().add(m.getDate() + " " + m.getTime());
                        }

                        hisData.getData().add(m.isInValid() ? "-" : m.getData().toString());
                    }
                }
            }
            retDataList.getRecords().add(hisData);
        }
        return new ResponseEntity<>(JSON.toJSONString(retDataList), HttpStatus.OK);
    }

    /**
     * 光伏/储能/充电桩页面头部右侧5个遥测数据
     * @param psrID 站点设备代码
     * @return
     */
    @GetMapping(value = "/substation/header/measurement")
    public ResponseEntity<List<MeasurementValue>> getDisplayTemplate(@RequestParam("id") String psrID) {

        BasePSR device = scadaPSRService.getDeviceByPsrId(psrID);
        DeviceTemplate deviceTemplate = psrTemplateMappingService.getDeviceTemplateByMapping(psrID);
        if (device == null || deviceTemplate == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        DisplayTemplate displayTemplate = displayTemplateService.getDisplayTemplateByAreaAndTemplate("substation_yc", deviceTemplate.getId());

        if (displayTemplate == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        List<DeviceTemplateData> deviceTemplateDatas = deviceTemplateDataService.getDeviceTemplateDataListByDeviceTemplateId(displayTemplate.getDeviceTemplateId());

        List<MeasurementValue> measurementValues = Lists.newArrayList();

        if (displayTemplate.isBatchMode()) {
            List<DeviceTemplateData> deviceTemplateDataList = Lists.newArrayList();
            if (displayTemplate.isBatchType1()) {
                deviceTemplateDataList = deviceTemplate.getDeviceTemplateByType(deviceTemplateDatas, 1);
            }
            if (displayTemplate.isBatchType2()) {
                deviceTemplateDataList = deviceTemplate.getDeviceTemplateByType(deviceTemplateDatas, 2);
            }


            for (DeviceTemplateData data : deviceTemplateDataList) {
                MeasurementValue m = new MeasurementValue().setO(device).setName(data.getName()).setRdb(true);
                m = generalDataService.getValue(m);
                m.setUnit(data.getUnit());
                measurementValues.add(m);
            }
        } else {
            List<DisplayTemplateData> displayTemplateDatas = displayTemplateDataService.getDisplayTemplateDataListByDisplayTemplateId(displayTemplate.getId());
            for (DisplayTemplateData displayTemplateData : displayTemplateDatas) {
                DeviceTemplateData deviceTemplateData = deviceTemplateDataService.getDeviceTemplateDataById(displayTemplateData.getDeviceTemplateDataId());
                String name = deviceTemplateData.getName();
                String comments = deviceTemplateData.getComments();
                MeasurementValue m = new MeasurementValue().setO(device).setName(name).setComments(comments);
                //统计值判断
                if (displayTemplateData.getFlag() != null) {
                    Flag flag = Flag.getFlag(displayTemplateData.getFlag());
                    m.setRdb(false).setFlag(flag).setTimestamp(TimeUtil.toMilliSeconds(LocalDateTime.now())).setComments(comments + flag.getN());

                    if (displayTemplateData.getDisplayTime()) {
                        m.setDisplayTime(true).setComments(comments + flag.getN() + "发生时间");
                    }

                } else {
                    m = m.setRdb(true);
                }
                m = generalDataService.getValue(m);
                m.setFormatter(displayTemplateData.getFormatter())
                        .setUnit(displayTemplateData.getUnit() != null ? displayTemplateData.getUnit() : deviceTemplateData.getUnit())
                        .setFunc(displayTemplateData.getFunc());
                measurementValues.add(m);
            }
        }
        return new ResponseEntity<>(measurementValues, HttpStatus.OK);

    }

}
